PHASE 2 · 路由器解剖

2.3DHCP 与 DNS 服务

dnsmasq 与 odhcpd

0.5 你学过设备开机怎么拿 IP(DHCP 的 DORA)、怎么把域名解析成 IP(DNS)。这章看这两件事在路由器上由谁干、怎么配——答案基本是一个进程:dnsmasq。它既是给 LAN 发地址的 DHCP 服务器,又是帮你查域名的 DNS 转发器。再加上管 IPv6 的 odhcpd,你 LAN 里"设备一插上就能上网"的魔法就齐了。这章就是 2.2 那条 /etc/config/dhcp → dnsmasq/odhcpd → 服务 流水线的展开。

一句话定义

在 OpenWRT 上,dnsmasq 一个进程同时充当 LAN 的 DHCP 服务器(0.5 发地址)和 DNS 转发缓存器(0.5 查域名);odhcpd 负责 IPv6 那半边(RA / DHCPv6)。它们都读 /etc/config/dhcp

1dnsmasq:一个进程,两个角色

一台设备开机上网,先要 DHCP 拿地址(0.5 的 D-O-R-A),紧接着几乎立刻要 DNS 解析域名(0.5)。这两件事都发生在 LAN 边界、都由路由器提供,dnsmasq 把它们打包成一个进程的两顶帽子:

↓ LAN 设备:DHCP 请求 + DNS 查询,都先到这里
dnsmasq · 一个进程,两个角色
① DHCP 服务器
从地址池发 IP + 网关 + DNS + 租期(0.5 DORA);把主机名登记进本地 DNS
② DNS 转发 + 缓存
本地主机名自己答;外部域名转发给上游 + 缓存结果(0.5)
↓ 外部域名查询 → 上游 DNS(1.1.1.1 / ISP)

而两顶帽子天然联动:dnsmasq 把它通过 DHCP 分出去的主机名,自动加进 DNS——所以你能用 ping 主机名 直接找到 LAN 里另一台设备(它给自己也当了个小型本地 DNS)。

类比:入职窗口 + 内部通讯录合体

新设备来了,窗口(DHCP)发给它工号(IP)、发工牌信息(网关 / DNS);同时把它登进通讯录(本地 DNS),别人就能按名字找到它。对外的查询(外部域名)它转给上游、并缓存下来。

2DHCP:发地址 + 静态租约

DHCP 侧配置在 /etc/config/dhcp,每个接口一个 dhcp 段:

/etc/config/dhcp
config dhcp 'lan'
    option interface 'lan'
    option start '100'        # 地址池起始(.100)
    option limit '150'        # 池大小(.100 → .249)
    option leasetime '12h'    # 租期

这定义了 LAN 的 DHCP 地址池:从 192.168.1.100 开始、150 个、租 12 小时。对应 0.5 的 DORA——设备 Discover,dnsmasq 从这个池 Offer 一个。想让某台设备(NAS、打印机、服务器)每次拿同一个 IP,用 host 段把它的 MAC 绑到一个 IP:

静态租约
config host
    option mac 'AA:BB:CC:DD:EE:FF'
    option ip '192.168.1.50'
    option name 'nas'

绑定基于 MAC(0.2 的 MAC 地址)。DHCP 还能下发一堆参数(网关、DNS、NTP、域名…),这些叫 DHCP options,每个有编号;dnsmasq 默认发合理值,要自定义就用 dhcp_option:

DHCP options
list dhcp_option '6,1.1.1.1,8.8.8.8'   # option 6 = DNS 服务器
list dhcp_option '42,192.168.1.1'      # option 42 = NTP 服务器
路由器关联 router-link

静态租约 + 端口转发是自建服务的标准组合:先在这给 NAS 固定 .50(本节),再在 fw4 里把公网端口 DNAT 到 192.168.1.50(2.4,落 0.6 的端口转发)。两步都依赖"设备有个稳定的内网 IP"——不然 DNAT 的目标会飘。

3DNS:转发、缓存、本地解析

回想 0.5 的 DNS 解析链。在你家网络里,dnsmasq 通常是这条链上离你最近的一环:

  1. LAN 设备(DNS 被 DHCP 设成了路由器,即 dnsmasq)发出查询;
  2. dnsmasq 先看能不能自己答:本地主机名、/etc/hosts、静态配置 → 直接回;
  3. 答不了的(外部域名),转发给上游 DNS(ISP 的,或你配的 1.1.1.1 / 8.8.8.8),拿到结果缓存、再返回;
  4. 下次同样查询命中缓存,直接答,快且省。

关键配置(在 /etc/config/dhcp 的 dnsmasq 段):

config dnsmasq
config dnsmasq
    option domain 'lan'           # 本地域名后缀
    option local '/lan/'          # /lan/ 结尾的查询本地解析、不外发
    list server '1.1.1.1'         # 上游 DNS(可多个)
    option cachesize '1000'       # 缓存条数
    option rebind_protection '1'  # 防 DNS 重绑定攻击

本地解析很实用:配了 domain 'lan',你就能用 nas.lan 访问那台 NAS(dnsmasq 把 DHCP 主机名 + 域名后缀拼起来解析)。整个内网有了自己的域名空间,不用记 IP。

这解释了很多"上网体验"

你换 DNS(为了更快或去广告)、内网设备互相用名字访问、DNS 查询变快——底层都是在调 dnsmasq 这一层。很多路由器的"去广告"(把广告域名解析到空地址)也是给 dnsmasq 灌一份 blocklist。它是你家 DNS 行为的总开关

路由器关联 router-link

DNS 分流(国内域名走国内 DNS、国外走国外)、DoH/DoT 加密上游、广告过滤,都是在 dnsmasq(或它的上游链)上做文章。2.7 的 DNS 分流会用到:dnsmasq 按域名把查询分给不同上游,配合 1.2 的策略路由把对应流量导向不同线路。

4IPv6:odhcpd 与 RA

回想 IPv6 加餐章:IPv6 设备主要靠 SLAAC(无状态自动配置)+ RA(路由通告)拿地址,而不是像 IPv4 那样必须问 DHCP。谁在你家发这些 RA?odhcpd。它干三件事:

  • 发 RA:告诉 LAN 的 IPv6 设备"本网段前缀是啥、我是网关",设备据此 SLAAC 自己生成地址(加餐章)。
  • 可选 DHCPv6:需要有状态分配 / 下发 DNS 时用。
  • 前缀委派(Prefix Delegation):从 WAN(ISP)拿到一段 IPv6 前缀,再分给 LAN——家庭 IPv6 联网的关键一步(ISP 给你一整段,你路由器把它下放到内网)。

配置也在 /etc/config/dhcp,每个接口的 dhcp 段里带 ra / dhcpv6 选项:

/etc/config/dhcp · IPv6
config dhcp 'lan'
    option interface 'lan'
    option ra 'server'          # 在 LAN 上发 RA
    option dhcpv6 'server'      # 提供 DHCPv6
    option ra_slaac '1'         # 允许 SLAAC
路由器关联 router-link

加餐章那句"IPv6 靠 RA/SLAAC 拿地址、每台设备直接全局可达"在这里落地:WAN 侧 odhcpd 通过 DHCPv6-PD 向 ISP 要前缀,LAN 侧发 RA 让设备自配地址。这也是为什么 IPv6 下你不需要 NAT(加餐章)——设备有真正的公网地址,路由器只转发、不改地址。IPv4 发地址(dnsmasq)+ IPv6 发前缀通告(odhcpd),双栈家庭网络的两半就齐了。

本章小结

  • dnsmasq 一个进程两个角色:LAN 的 DHCP 服务器(0.5 DORA 发地址)+ DNS 转发缓存器(0.5 查域名);两者联动(DHCP 主机名自动进本地 DNS)。
  • DHCP 侧(/etc/config/dhcp):地址池(start/limit/leasetime)、静态租约(host 段按 MAC 绑固定 IP,配自建服务)、DHCP options(下发网关/DNS/NTP)。
  • DNS 侧:转发缓存解析器——本地名自己答、外部名转上游并缓存;domain 'lan' 给内网自有域名空间;换 DNS / 去广告 / 分流都在这层。
  • IPv6:odhcpd 发 RA(SLAAC,加餐章)+ 可选 DHCPv6 + 前缀委派(从 ISP 拿前缀下放 LAN);落地"IPv6 无需 NAT、设备直接可达"。
  • 全在 2.2 框架内:/etc/config/dhcp → dnsmasq/odhcpd → 服务;这章把 0.5 与加餐章的抽象接到了实际配置。

动手练习

  1. 若有 OpenWRT:cat /etc/config/dhcp,认出 lan 的 dhcp 段(start/limit/leasetime)和 dnsmasq 段(server/domain);对照本章说出各项作用。
  2. 给一台设备加静态租约(host 段:MAC → 固定 IP → name),reload dnsmasq,确认它下次拿到固定 IP,并能用 名字.lan 访问。
  3. 思考题:为什么设备一插上就能"用名字互相访问"?dnsmasq 的哪两个角色在联动?(DHCP 登记主机名 → 本地 DNS 能解析它。)
  4. 进阶:把本章和 0.5 对照——画出你手机开机到打开网页的完整过程,标出每步是 dnsmasq 的哪个角色(DORA 四步 = DHCP 角色;解析 example.com = DNS 转发;命中缓存 = DNS 缓存)。